﻿using System;
using System.Collections;
using System.Collections.Generic;
using Mono.Cecil;

namespace Mono.Collections.Generic
{
	// Token: 0x0200000C RID: 12
	public class Collection<T> : IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable, IList, ICollection
	{
		// Token: 0x17000001 RID: 1
		// (get) Token: 0x0600002E RID: 46 RVA: 0x00009B68 File Offset: 0x00007D68
		public int Count
		{
			get
			{
				return this.size;
			}
		}

		// Token: 0x17000002 RID: 2
		public T this[int index]
		{
			get
			{
				bool flag = index >= this.size;
				if (flag)
				{
					throw new ArgumentOutOfRangeException();
				}
				return this.items[index];
			}
			set
			{
				this.CheckIndex(index);
				bool flag = index == this.size;
				if (flag)
				{
					throw new ArgumentOutOfRangeException();
				}
				this.OnSet(value, index);
				this.items[index] = value;
			}
		}

		// Token: 0x17000003 RID: 3
		// (get) Token: 0x06000031 RID: 49 RVA: 0x00009BF4 File Offset: 0x00007DF4
		// (set) Token: 0x06000032 RID: 50 RVA: 0x00009C10 File Offset: 0x00007E10
		public int Capacity
		{
			get
			{
				return this.items.Length;
			}
			set
			{
				bool flag = value < 0 || value < this.size;
				if (flag)
				{
					throw new ArgumentOutOfRangeException();
				}
				this.Resize(value);
			}
		}

		// Token: 0x17000004 RID: 4
		// (get) Token: 0x06000033 RID: 51 RVA: 0x00009C40 File Offset: 0x00007E40
		bool ICollection<T>.IsReadOnly
		{
			get
			{
				return false;
			}
		}

		// Token: 0x17000005 RID: 5
		// (get) Token: 0x06000034 RID: 52 RVA: 0x00009C40 File Offset: 0x00007E40
		bool IList.IsFixedSize
		{
			get
			{
				return false;
			}
		}

		// Token: 0x17000006 RID: 6
		// (get) Token: 0x06000035 RID: 53 RVA: 0x00009C40 File Offset: 0x00007E40
		bool IList.IsReadOnly
		{
			get
			{
				return false;
			}
		}

		// Token: 0x17000007 RID: 7
		object IList.this[int index]
		{
			get
			{
				return this[index];
			}
			set
			{
				this.CheckIndex(index);
				try
				{
					this[index] = (T)((object)value);
					return;
				}
				catch (InvalidCastException)
				{
				}
				catch (NullReferenceException)
				{
				}
				throw new ArgumentException();
			}
		}

		// Token: 0x17000008 RID: 8
		// (get) Token: 0x06000038 RID: 56 RVA: 0x00009CC8 File Offset: 0x00007EC8
		int ICollection.Count
		{
			get
			{
				return this.Count;
			}
		}

		// Token: 0x17000009 RID: 9
		// (get) Token: 0x06000039 RID: 57 RVA: 0x00009C40 File Offset: 0x00007E40
		bool ICollection.IsSynchronized
		{
			get
			{
				return false;
			}
		}

		// Token: 0x1700000A RID: 10
		// (get) Token: 0x0600003A RID: 58 RVA: 0x00009CE0 File Offset: 0x00007EE0
		object ICollection.SyncRoot
		{
			get
			{
				return this;
			}
		}

		// Token: 0x0600003B RID: 59 RVA: 0x000029C1 File Offset: 0x00000BC1
		public Collection()
		{
			this.items = Empty<T>.Array;
		}

		// Token: 0x0600003C RID: 60 RVA: 0x00009CF4 File Offset: 0x00007EF4
		public Collection(int capacity)
		{
			bool flag = capacity < 0;
			if (flag)
			{
				throw new ArgumentOutOfRangeException();
			}
			this.items = ((capacity == 0) ? Empty<T>.Array : new T[capacity]);
		}

		// Token: 0x0600003D RID: 61 RVA: 0x00009D30 File Offset: 0x00007F30
		public Collection(ICollection<T> items)
		{
			bool flag = items == null;
			if (flag)
			{
				throw new ArgumentNullException("items");
			}
			this.items = new T[items.Count];
			items.CopyTo(this.items, 0);
			this.size = this.items.Length;
		}

		// Token: 0x0600003E RID: 62 RVA: 0x00009D88 File Offset: 0x00007F88
		public void Add(T item)
		{
			bool flag = this.size == this.items.Length;
			if (flag)
			{
				this.Grow(1);
			}
			this.OnAdd(item, this.size);
			T[] array = this.items;
			int num = this.size;
			this.size = num + 1;
			array[num] = item;
			this.version++;
		}

		// Token: 0x0600003F RID: 63 RVA: 0x00009DEC File Offset: 0x00007FEC
		public bool Contains(T item)
		{
			return this.IndexOf(item) != -1;
		}

		// Token: 0x06000040 RID: 64 RVA: 0x00009E0C File Offset: 0x0000800C
		public int IndexOf(T item)
		{
			return Array.IndexOf<T>(this.items, item, 0, this.size);
		}

		// Token: 0x06000041 RID: 65 RVA: 0x00009E34 File Offset: 0x00008034
		public void Insert(int index, T item)
		{
			this.CheckIndex(index);
			bool flag = this.size == this.items.Length;
			if (flag)
			{
				this.Grow(1);
			}
			this.OnInsert(item, index);
			this.Shift(index, 1);
			this.items[index] = item;
			this.version++;
		}

		// Token: 0x06000042 RID: 66 RVA: 0x00009E94 File Offset: 0x00008094
		public void RemoveAt(int index)
		{
			bool flag = index < 0 || index >= this.size;
			if (flag)
			{
				throw new ArgumentOutOfRangeException();
			}
			T item = this.items[index];
			this.OnRemove(item, index);
			this.Shift(index, -1);
			this.version++;
		}

		// Token: 0x06000043 RID: 67 RVA: 0x00009EEC File Offset: 0x000080EC
		public bool Remove(T item)
		{
			int num = this.IndexOf(item);
			bool flag = num == -1;
			bool result;
			if (flag)
			{
				result = false;
			}
			else
			{
				this.OnRemove(item, num);
				this.Shift(num, -1);
				this.version++;
				result = true;
			}
			return result;
		}

		// Token: 0x06000044 RID: 68 RVA: 0x000029D6 File Offset: 0x00000BD6
		public void Clear()
		{
			this.OnClear();
			Array.Clear(this.items, 0, this.size);
			this.size = 0;
			this.version++;
		}

		// Token: 0x06000045 RID: 69 RVA: 0x00002A08 File Offset: 0x00000C08
		public void CopyTo(T[] array, int arrayIndex)
		{
			Array.Copy(this.items, 0, array, arrayIndex, this.size);
		}

		// Token: 0x06000046 RID: 70 RVA: 0x00009F34 File Offset: 0x00008134
		public T[] ToArray()
		{
			T[] array = new T[this.size];
			Array.Copy(this.items, 0, array, 0, this.size);
			return array;
		}

		// Token: 0x06000047 RID: 71 RVA: 0x00009F68 File Offset: 0x00008168
		private void CheckIndex(int index)
		{
			bool flag = index < 0 || index > this.size;
			if (flag)
			{
				throw new ArgumentOutOfRangeException();
			}
		}

		// Token: 0x06000048 RID: 72 RVA: 0x00009F90 File Offset: 0x00008190
		private void Shift(int start, int delta)
		{
			bool flag = delta < 0;
			if (flag)
			{
				start -= delta;
			}
			bool flag2 = start < this.size;
			if (flag2)
			{
				Array.Copy(this.items, start, this.items, start + delta, this.size - start);
			}
			this.size += delta;
			bool flag3 = delta < 0;
			if (flag3)
			{
				Array.Clear(this.items, this.size, -delta);
			}
		}

		// Token: 0x06000049 RID: 73 RVA: 0x00002A20 File Offset: 0x00000C20
		protected virtual void OnAdd(T item, int index)
		{
		}

		// Token: 0x0600004A RID: 74 RVA: 0x00002A20 File Offset: 0x00000C20
		protected virtual void OnInsert(T item, int index)
		{
		}

		// Token: 0x0600004B RID: 75 RVA: 0x00002A20 File Offset: 0x00000C20
		protected virtual void OnSet(T item, int index)
		{
		}

		// Token: 0x0600004C RID: 76 RVA: 0x00002A20 File Offset: 0x00000C20
		protected virtual void OnRemove(T item, int index)
		{
		}

		// Token: 0x0600004D RID: 77 RVA: 0x00002A20 File Offset: 0x00000C20
		protected virtual void OnClear()
		{
		}

		// Token: 0x0600004E RID: 78 RVA: 0x0000A000 File Offset: 0x00008200
		internal virtual void Grow(int desired)
		{
			int num = this.size + desired;
			bool flag = num <= this.items.Length;
			if (!flag)
			{
				num = Math.Max(Math.Max(this.items.Length * 2, 4), num);
				this.Resize(num);
			}
		}

		// Token: 0x0600004F RID: 79 RVA: 0x0000A04C File Offset: 0x0000824C
		protected void Resize(int new_size)
		{
			bool flag = new_size == this.size;
			if (!flag)
			{
				bool flag2 = new_size < this.size;
				if (flag2)
				{
					throw new ArgumentOutOfRangeException();
				}
				this.items = this.items.Resize(new_size);
			}
		}

		// Token: 0x06000050 RID: 80 RVA: 0x0000A090 File Offset: 0x00008290
		int IList.Add(object value)
		{
			try
			{
				this.Add((T)((object)value));
				return this.size - 1;
			}
			catch (InvalidCastException)
			{
			}
			catch (NullReferenceException)
			{
			}
			throw new ArgumentException();
		}

		// Token: 0x06000051 RID: 81 RVA: 0x00002A23 File Offset: 0x00000C23
		void IList.Clear()
		{
			this.Clear();
		}

		// Token: 0x06000052 RID: 82 RVA: 0x0000A0E4 File Offset: 0x000082E4
		bool IList.Contains(object value)
		{
			return ((IList)this).IndexOf(value) > -1;
		}

		// Token: 0x06000053 RID: 83 RVA: 0x0000A100 File Offset: 0x00008300
		int IList.IndexOf(object value)
		{
			try
			{
				return this.IndexOf((T)((object)value));
			}
			catch (InvalidCastException)
			{
			}
			catch (NullReferenceException)
			{
			}
			return -1;
		}

		// Token: 0x06000054 RID: 84 RVA: 0x0000A14C File Offset: 0x0000834C
		void IList.Insert(int index, object value)
		{
			this.CheckIndex(index);
			try
			{
				this.Insert(index, (T)((object)value));
				return;
			}
			catch (InvalidCastException)
			{
			}
			catch (NullReferenceException)
			{
			}
			throw new ArgumentException();
		}

		// Token: 0x06000055 RID: 85 RVA: 0x0000A1A0 File Offset: 0x000083A0
		void IList.Remove(object value)
		{
			try
			{
				this.Remove((T)((object)value));
			}
			catch (InvalidCastException)
			{
			}
			catch (NullReferenceException)
			{
			}
		}

		// Token: 0x06000056 RID: 86 RVA: 0x00002A2D File Offset: 0x00000C2D
		void IList.RemoveAt(int index)
		{
			this.RemoveAt(index);
		}

		// Token: 0x06000057 RID: 87 RVA: 0x00002A08 File Offset: 0x00000C08
		void ICollection.CopyTo(Array array, int index)
		{
			Array.Copy(this.items, 0, array, index, this.size);
		}

		// Token: 0x06000058 RID: 88 RVA: 0x0000A1E8 File Offset: 0x000083E8
		public Collection<T>.Enumerator GetEnumerator()
		{
			return new Collection<T>.Enumerator(this);
		}

		// Token: 0x06000059 RID: 89 RVA: 0x0000A200 File Offset: 0x00008400
		IEnumerator IEnumerable.GetEnumerator()
		{
			return new Collection<T>.Enumerator(this);
		}

		// Token: 0x0600005A RID: 90 RVA: 0x0000A220 File Offset: 0x00008420
		IEnumerator<T> IEnumerable<T>.GetEnumerator()
		{
			return new Collection<T>.Enumerator(this);
		}

		// Token: 0x0400000B RID: 11
		internal T[] items;

		// Token: 0x0400000C RID: 12
		internal int size;

		// Token: 0x0400000D RID: 13
		private int version;

		// Token: 0x0200000D RID: 13
		public struct Enumerator : IEnumerator<T>, IDisposable, IEnumerator
		{
			// Token: 0x1700000B RID: 11
			// (get) Token: 0x0600005B RID: 91 RVA: 0x0000A240 File Offset: 0x00008440
			public T Current
			{
				get
				{
					return this.current;
				}
			}

			// Token: 0x1700000C RID: 12
			// (get) Token: 0x0600005C RID: 92 RVA: 0x0000A258 File Offset: 0x00008458
			object IEnumerator.Current
			{
				get
				{
					this.CheckState();
					bool flag = this.next <= 0;
					if (flag)
					{
						throw new InvalidOperationException();
					}
					return this.current;
				}
			}

			// Token: 0x0600005D RID: 93 RVA: 0x00002A38 File Offset: 0x00000C38
			internal Enumerator(Collection<T> collection)
			{
				this = default(Collection<T>.Enumerator);
				this.collection = collection;
				this.version = collection.version;
			}

			// Token: 0x0600005E RID: 94 RVA: 0x0000A294 File Offset: 0x00008494
			public bool MoveNext()
			{
				this.CheckState();
				bool flag = this.next < 0;
				bool result;
				if (flag)
				{
					result = false;
				}
				else
				{
					bool flag2 = this.next < this.collection.size;
					if (flag2)
					{
						T[] items = this.collection.items;
						int num = this.next;
						this.next = num + 1;
						this.current = items[num];
						result = true;
					}
					else
					{
						this.next = -1;
						result = false;
					}
				}
				return result;
			}

			// Token: 0x0600005F RID: 95 RVA: 0x00002A55 File Offset: 0x00000C55
			public void Reset()
			{
				this.CheckState();
				this.next = 0;
			}

			// Token: 0x06000060 RID: 96 RVA: 0x0000A30C File Offset: 0x0000850C
			private void CheckState()
			{
				bool flag = this.collection == null;
				if (flag)
				{
					throw new ObjectDisposedException(base.GetType().FullName);
				}
				bool flag2 = this.version != this.collection.version;
				if (flag2)
				{
					throw new InvalidOperationException();
				}
			}

			// Token: 0x06000061 RID: 97 RVA: 0x00002A66 File Offset: 0x00000C66
			public void Dispose()
			{
				this.collection = null;
			}

			// Token: 0x0400000E RID: 14
			private Collection<T> collection;

			// Token: 0x0400000F RID: 15
			private T current;

			// Token: 0x04000010 RID: 16
			private int next;

			// Token: 0x04000011 RID: 17
			private readonly int version;
		}
	}
}
